像函数一样使用 Blocks
前提条件:本指南基于 Blocks 的基本介绍。请确保已先阅读 Blocks 与事件监听 和 布局控制 指南。
介绍
除了作为全栈机器学习演示界面外,Gradio Blocks 应用实际上也可以被当作普通的 Python 函数使用!
这意味着如果您有一个名为 demo
的 Gradio Blocks (或 Interface) 应用,您可以像使用任何普通 Python 函数一样使用它。
例如,执行 output = demo("Hello", "friend")
将在输入 "Hello" 和 "friend" 上运行 demo
中定义的第一个事件,并将结果存储在变量 output
中。
通过将应用程序作为函数使用,您可以实现不同 Gradio 应用之间的无缝组合。下面我们将详细介绍如何实现这一点。
将 Blocks 作为函数使用
假设我们有以下演示应用,它将英文文本翻译成德文:
import gradio as gr
from transformers import pipeline
pipe = pipeline("translation", model="t5-base")
def translate(text):
return pipe(text)[0]["translation_text"]
with gr.Blocks() as demo:
with gr.Row():
with gr.Column():
english = gr.Textbox(label="英文文本")
translate_btn = gr.Button(value="翻译")
with gr.Column():
german = gr.Textbox(label="德文文本")
translate_btn.click(translate, inputs=english, outputs=german, api_name="translate-to-german")
examples = gr.Examples(examples=["I went to the supermarket yesterday.", "Helen is a good swimmer."],
inputs=[english])
demo.launch()
现在,假设您有另一个生成英文文本的应用程序,但您还想生成德文文本。您有两种选择:
- 复制上面英文到德文翻译的源代码并粘贴到您的应用程序中。
- 在您的应用程序中加载上述英文到德文的翻译应用,并将其作为普通 Python 函数使用。
第一种方法虽然技术上总是可行的,但通常会引入不必要的复杂性和代码重复。
第二种方法允许您借用所需的功能,而不必将两个应用程序紧密耦合在一起。
要实现这一点,您只需要在您的源文件中调用 gr.load
类方法。之后,您就可以像使用普通 Python 函数一样使用翻译应用!
以下代码片段和演示展示了如何使用 gr.load
:
import gradio as gr
from transformers import pipeline
# 加载已部署的英文翻译器应用(也可以是本地应用)
english_translator = gr.load(name="spaces/gradio/english_translator")
# 创建文本生成器
english_generator = pipeline("text-generation", model="distilgpt2")
def generate_text(text):
# 生成英文文本
english_text = english_generator(text)[0]["generated_text"]
# 使用加载的翻译器应用将英文翻译成德文
german_text = english_translator(english_text)
return english_text, german_text
with gr.Blocks() as demo:
with gr.Row():
with gr.Column():
seed = gr.Text(label="输入短语")
with gr.Column():
english = gr.Text(label="生成的英文文本")
german = gr.Text(label="生成的德文文本")
btn = gr.Button("生成")
btn.click(generate_text, inputs=[seed], outputs=[english, german])
gr.Examples(["My name is Clara and I am"], inputs=[seed])
demo.launch()
请注意,变量 english_translator
是我们的英文到德文翻译应用,但它在 generate_text
函数中像普通函数一样被调用。
加载本地 Blocks 应用
除了加载已部署在 Hugging Face Spaces 上的应用,您还可以直接在同一个 Python 脚本中加载本地定义的 Blocks 应用:
import gradio as gr
# 定义一个简单的翻译应用
def reverse_text(text):
return text[::-1]
with gr.Blocks() as text_reverser:
input_text = gr.Textbox(label="输入文本")
output_text = gr.Textbox(label="反转后的文本")
reverse_btn = gr.Button("反转")
reverse_btn.click(reverse_text, inputs=input_text, outputs=output_text)
# 在另一个应用中使用这个 Blocks 应用
def process_text(text):
# 直接使用 text_reverser 作为函数
reversed_text = text_reverser(text)
return f"原文: {text}, 反转后: {reversed_text}"
with gr.Blocks() as demo:
input_box = gr.Textbox(label="请输入文本")
output_box = gr.Textbox(label="处理结果")
process_btn = gr.Button("处理")
process_btn.click(process_text, inputs=input_box, outputs=output_box)
demo.launch()
控制使用应用中的哪个函数
如果您加载的应用定义了多个函数,您可以使用 fn_index
和 api_name
参数来指定要使用的函数。
在我们的英文到德文演示代码中,您会看到以下行:
translate_btn.click(translate, inputs=english, outputs=german, api_name="translate-to-german")
api_name
在我们的应用中为这个函数提供了一个唯一的名称。您可以使用这个名称来告诉 Gradio 您想要使用上游应用中的哪个函数:
english_translator(text, api_name="translate-to-german")
您也可以使用 fn_index
参数。想象一下,如果我们的应用还定义了一个英文到西班牙文的翻译功能。要在我们的文本生成应用中使用它,我们可以使用以下代码:
english_translator(text, fn_index=1)
Gradio Spaces 中的函数索引从零开始,因此西班牙语翻译器作为我们应用中的第二个函数,索引为 1。
Gradio 客户端与应用加载
Gradio 还提供了一个客户端 API,可以更灵活地与远程 Gradio 应用交互:
import gradio as gr
from gradio.client import Client
# 使用客户端连接到远程应用
client = Client("spaces/gradio/english_translator")
def generate_and_translate(text):
# 使用客户端调用应用的特定函数
result = client.predict(text, api_name="translate-to-german")
return result
with gr.Blocks() as demo:
input_text = gr.Textbox(label="输入英文")
output_text = gr.Textbox(label="德文翻译")
translate_btn = gr.Button("翻译")
translate_btn.click(generate_and_translate, inputs=input_text, outputs=output_text)
demo.launch()
客户端 API 提供了更多控制选项,如设置超时、处理认证和管理并发请求等。
应用加载的最佳实践
选择正确的加载方法:
- 对于简单的功能重用,直接使用 Blocks 应用作为函数。
- 对于远程应用,使用
gr.load()
或客户端 API。 - 对于需要更多控制的场景,使用 Gradio 客户端。
错误处理:当使用远程应用时,添加适当的错误处理机制:
pythondef safe_translate(text): try: return english_translator(text) except Exception as e: return f"翻译失败: {str(e)}"
性能考虑:加载远程应用会增加网络延迟。如果性能关键,考虑在本地复制相关功能。
版本控制:当依赖远程应用时,确保处理API变化的可能性:
pythonenglish_translator = gr.load( name="spaces/gradio/english_translator", version="1.0.0" # 指定版本以确保兼容性 )
结论
将 Gradio Blocks 应用作为函数使用是一种强大的模式,它可以帮助您组合不同应用之间的功能。任何 Blocks 应用都可以被作为函数使用,但一个特别有效的模式是先 load
托管在 Hugging Face Spaces 上的应用,然后将其作为函数在您自己的应用中使用。您还可以加载托管在 Hugging Face Model Hub 上的模型(参考课程视频中的相关演示)。
这种模块化和可组合的方法可以大大提高开发效率,减少代码重复,并让您的应用更加灵活和可维护。